#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "MyString.h"
#include "DynamicArray.h"
#define Map_Size 5

//player
struct Player
{
    int HP;
    int attack;
    int x;
    int y;
};

struct Monster
{
    MyString name;
    int HP;
    int attack;
    int x;
    int y;
};

struct Treasure
{
    MyString name;
    int value;
    int x;
    int y;
};


void InitPlayer(struct Player *player)
{
    player->HP = 100;
    player->attack = 10;
    player->x = 0;
    player->y = 0;
}

int GetRandNumber(int max)
{
    return rand() % max;
}

struct Monster* CreateMonster(const char *Name,int hp,int Attack)
{
    struct Monster *monster = (struct Monster *)malloc(sizeof(struct Monster));
    if(monster == NULL)
    {
        printf("Monster malloc Error!\n");
        return NULL;
    }
    StringInitialize(&monster->name,Name);
    monster->HP = hp;
    monster->attack = Attack;
    
    monster->x = GetRandNumber(Map_Size);
    monster->y = GetRandNumber(Map_Size);

    return monster;
}

struct Treasure* CreateTreasure(const char *name,int value)
{
    struct Treasure * treasure = (struct Treasure *)malloc(sizeof(struct Treasure));
    if(treasure == NULL)
    {
        printf("Treasure malloc Error!\n");
        return NULL;
    }

    StringInitialize(&treasure->name,name);
    treasure->value = value;
    
    treasure->x = GetRandNumber(Map_Size);
    treasure->y = GetRandNumber(Map_Size);
    return treasure;
}

int InitMonsters(struct DynamicArray *monsters)
{
    if(Initialize(monsters) == false)
    {
        return false;
    }
    InsertArray(monsters,CreateMonster("巨龙",100,20));
    InsertArray(monsters,CreateMonster("半人马",50,10));
    InsertArray(monsters,CreateMonster("半人马",50,10));
    InsertArray(monsters,CreateMonster("哥布林",10,2));
    InsertArray(monsters,CreateMonster("哥布林",10,2));
    InsertArray(monsters,CreateMonster("哥布林",10,2));
    InsertArray(monsters,CreateMonster("哥布林",10,2));
    return true;
}

int InitTreasure(struct DynamicArray *treasures)
{
    if(Initialize(treasures) == false)
    {
        return false;
    }
    InsertArray(treasures,CreateTreasure("宝箱",500));
    InsertArray(treasures,CreateTreasure("宝箱",500));
    InsertArray(treasures,CreateTreasure("宝箱",500));
    InsertArray(treasures,CreateTreasure("金钱",100));
    InsertArray(treasures,CreateTreasure("金钱",100));
    InsertArray(treasures,CreateTreasure("药品",5));
    InsertArray(treasures,CreateTreasure("药品",10));
    return true;
}


void MakeMove(struct Player *player,int dx,int dy)
{
    player->x += dx;
    player->y += dy;
    if(player->x < 0) player->x = 0;
    if(player->x >= Map_Size) player->x = Map_Size-1;
    if(player->y < 0) player->y = 0;
    if(player->y >= Map_Size) player->y = Map_Size-1;
}

int Battle(struct Player *player, struct Monster *monster)
{
    printf("您遭遇到了怪兽%s  血量:%d 攻击力:%d\n",monster->name.string,monster->HP,monster->attack);
    while(1)
    {
        
        printf("请选择你的行动:1、攻击  2、防御  3、逃跑\n");
        printf("请选择:");
        int choice = 0;
        scanf("%d",&choice);
        switch (choice)
        {
        case 1:
            printf("你对怪兽造成了 %d 伤害\n",player->attack);
            printf("怪兽对你进行了还击，造成 %d 伤害\n",monster->attack);
            player->HP -= monster->attack;
            monster->HP -= player->attack;
            break;
        case 2:
            printf("怪兽对你进行了攻击!\n");
            if(GetRandNumber(2) == 1)
            {
                printf("你防御住了!\n");
            }
            else
            {
                printf("怪兽破坏了你的防御,对你造成了%d伤害!\n",monster->attack);
                player->HP -= monster->attack;
            }
            break;
            
        case 3:
            if(GetRandNumber(2) == 1)
            {
                printf("逃跑成功!\n");
                return true;
            }
            else
            {
                printf("逃跑失败!\n");
                printf("怪兽对你造成了%d伤害!\n",monster->attack);
                player->HP -= monster->attack;
            }
            break;

        default:
            break;
        }
        if(monster->HP  <= 0)
        {
            monster->HP = 0;
            printf("你战胜了怪兽!\n");
            return true;
        }
        if(player->HP  <= 0)
        {
            player->HP = 0;
            printf("怪兽打败了你!\n");
            return false;
        }
        printf("当前怪物的剩余血量: %d\n",monster->HP);
        printf("当前你的剩余血量: %d\n",player->HP);
    }

}



int main()
{
    srand(time(NULL));

    struct Player player;
    InitPlayer(&player);

    struct DynamicArray monsters = {NULL,10,0};
    InitMonsters(&monsters);

    struct DynamicArray treasures= {NULL,10,0};
    InitTreasure(&treasures);


    printf("欢迎来到魔塔世界!\n");

    while(1)
    {
       system("clear");
       printf("你当前所在的位置是 : < %d, %d>\n",player.x,player.y);

        for(int i = 0; i < monsters.len; i++)
        {
            struct Monster *monster = (struct Monster *)monsters.dp[i];
            if(monster->HP > 0 && monster->x == player.x && monster->y == player.y)
            {
                if(Battle(&player,monster) == false)
                {   
                    printf("您被击败了！游戏结束！\n");
                    break;
                }
            }
        }

        for(int i = 0; i < treasures.len; i++)
        {
            struct Treasure *treasure = (struct Treasure *)treasures.dp[i];
            if(treasure->value != 0 &&treasure->x == player.x && treasure->y == player.y)
            {
                printf("您获得了%s,价值是%d\n",treasure->name.string,treasure->value);
                treasure->value = 0;
            }
        }

        printf("请按 'w' 'a' 's' 'd'进行移动:");
        char move = 0;
        scanf("%c",&move);

        switch (move)
        {
        case 'w':
            MakeMove(&player,0,1);
            break;
        case 's':
            MakeMove(&player,0,-1);
            break;
        case 'a':
            MakeMove(&player,-1,0);
            break;
        case 'd':
            MakeMove(&player,1,0);
            break;
        
        default:
            break;
        }
    }

    for(int i = 0; i < monsters.len; i++)
    {
        free((struct Monster*)monsters.dp[i]);
    }
    free(monsters.dp);

     for(int i = 0; i < treasures.len; i++)
    {
        free((struct Treasure*)treasures.dp[i]);
    }
    free(treasures.dp);

    return 0;
}